Skip to content

feat(input): 新增统一输入抽象与Godot集成#346

Merged
GeWuYou merged 3 commits into
mainfrom
feat/input-system-godot-integration
May 11, 2026
Merged

feat(input): 新增统一输入抽象与Godot集成#346
GeWuYou merged 3 commits into
mainfrom
feat/input-system-godot-integration

Conversation

@GeWuYou

@GeWuYou GeWuYou commented May 10, 2026

Copy link
Copy Markdown
Owner
  • 新增输入绑定 DTO、设备上下文和 UI 语义桥接契约。

  • 实现 Game 默认输入绑定存储、动作映射和 UI 分发桥接。

  • 落地 Godot InputMap 适配、测试覆盖与配套文档。

  • 更新 ai-plan 恢复点、worktree 映射与采用入口。

Summary by CodeRabbit

发布说明

  • New Features

    • 推出输入绑定管理系统,支持绑定快照导入/导出、主绑定设置与冲突交换。
    • 增加输入设备追踪以识别当前活跃设备。
    • 新增 UI 输入动作映射与分发机制。
    • 完成 Godot InputMap 的集成适配。
  • Tests

    • 新增输入绑定存储、UI 分发器及 Godot 集成的单元测试。
  • Documentation

    • 补充输入系统设计文档与 Godot 集成指南。

Review Change Stack

- 新增输入绑定 DTO、设备上下文和 UI 语义桥接契约。

- 实现 Game 默认输入绑定存储、动作映射和 UI 分发桥接。

- 落地 Godot InputMap 适配、测试覆盖与配套文档。

- 更新 ai-plan 恢复点、worktree 映射与采用入口。
@coderabbitai

coderabbitai Bot commented May 10, 2026

Copy link
Copy Markdown
Contributor

Warning

Rate limit exceeded

@GeWuYou has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 34 minutes and 25 seconds before requesting another review.

You’ve run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 8fde6cc4-7f3f-47c6-8ca9-4c56f4441dd3

📥 Commits

Reviewing files that changed from the base of the PR and between 5f9589e and 158f98a.

📒 Files selected for processing (6)
  • GFramework.Game/Input/InputBindingStore.cs
  • GFramework.Godot.Tests/Input/GodotInputBindingStoreTests.cs
  • GFramework.Godot/Input/GodotInputBindingCodec.cs
  • GFramework.Godot/Input/GodotInputMapBackend.cs
  • ai-plan/public/input-system-godot-integration/todos/input-system-godot-integration-tracking.md
  • ai-plan/public/input-system-godot-integration/traces/input-system-godot-integration-trace.md
📝 Walkthrough

Walkthrough

新增输入抽象与 DTO(动作绑定、描述符、快照、设备上下文、枚举、接口),在 Game 层实现托管 InputBindingStore、设备追踪与 UI 映射/分发;在 Godot 层新增编解码器、InputMap 后端适配与 GodotInputBindingStore;附带单元测试与中文文档。

变更

输入系统完整实现

层 / 文件(s) 摘要
契约层数据模型
GFramework.Game.Abstractions/Input/IInputBindingStore.cs, IInputDeviceTracker.cs, IUiInputActionMap.cs, IUiInputDispatcher.cs, InputBindingKind.cs, InputDeviceKind.cs, InputBindingDescriptor.cs, InputActionBinding.cs, InputBindingSnapshot.cs, InputDeviceContext.cs
定义四个核心接口(绑定存储、设备追踪、UI 动作映射、UI 分发)及完整 DTO 契约(描述符、快照、绑定、设备上下文、枚举)。
Game 核心存储
GFramework.Game/Input/InputBindingStore.cs
托管实现 IInputBindingStore:默认快照恢复、主绑定替换、等价性绑定去重、可选冲突交换(交换另一动作的前期绑定)、快照导入导出。
Game 设备追踪与 UI 桥接
GFramework.Game/Input/InputDeviceTracker.cs, UiInputActionMap.cs, UiInputDispatcher.cs
实现 IInputDeviceTracker(初始化 Unknown,支持 Update)、IUiInputActionMap(case-insensitive 映射含 Godot 风格别名)、IUiInputDispatcher(通过 IUiRouter 分发)。
Godot 编解码器
GFramework.Godot/Input/GodotInputBindingCodec.cs
双向转换:TryCreateBinding 从 InputEvent 推导描述符(键盘、鼠标、手柄按键、手柄轴);CreateInputEvent 从描述符重建事件;GetDeviceContext 推断设备类型。
Godot 后端接口与实现
GFramework.Godot/Input/IGodotInputMapBackend.cs, GodotInputMapBackend.cs
最小后端契约与实现:构造时捕获默认绑定,动作名枚举、绑定读写、单个/全部重置或清空。
Godot 绑定存储适配
GFramework.Godot/Input/GodotInputBindingStore.cs
同时实现 IInputBindingStore + IInputDeviceTracker,包装后端与内部 InputBindingStore,支持快照导出/导入、设备追踪更新、后端同步与缺失动作清空语义。
Game 层测试
GFramework.Game.Tests/Input/InputBindingStoreTests.cs, UiInputDispatcherTests.cs
绑定冲突交换、全部重置、GetBindings 未污染快照、UI 动作映射及路由转发验证。
Godot 层测试
GFramework.Godot.Tests/Input/GodotInputBindingStoreTests.cs
快照导出/导入、缺失动作导致后端清空、绑定冲突交换及后端同步,含 FakeInputMapBackend 纯托管测试双。
文档与项目规划
GFramework.Game.Abstractions/README.md, GFramework.Game/README.md, GFramework.Godot/README.md, ai-plan/public/README.md, ai-plan/public/input-system-godot-integration/*, docs/zh-CN/game/index.md, docs/zh-CN/game/input.md, docs/zh-CN/godot/index.md, docs/zh-CN/godot/input.md, docs/zh-CN/tutorials/godot-integration.md
更新导航、新增用户文档(契约概览、Game 运行时、Godot 集成、最小接入示例)、项目追踪与 trace 文档(恢复点、已添加回归测试、下一步)。

预计代码审查工作量

🎯 4 (复杂) | ⏱️ ~50 分钟

可能相关的 PR

  • GeWuYou/GFramework#249:主 PR 的 UI 输入分发(UiInputDispatcher 与 UiInputActionMap)直接依赖该 PR 中的 UI 路由契约(UiInputAction、IUiRouter.TryDispatchUiAction)。
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 74.70% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed 标题「feat(input): 新增统一输入抽象与Godot集成」清晰准确地概括了本次变更的核心内容,涵盖了新增输入层抽象契约、Game层默认实现及Godot适配这三个主要维度。
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/input-system-godot-integration

Tip

💬 Introducing Slack Agent: The best way for teams to turn conversations into code.

Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.

  • Generate code and open pull requests
  • Plan features and break down work
  • Investigate incidents and troubleshoot customer tickets together
  • Automate recurring tasks and respond to alerts with triggers
  • Summarize progress and report instantly

Built for teams:

  • Shared memory across your entire org—no repeating context
  • Per-thread sandboxes to safely plan and execute work
  • Governance built-in—scoped access, auditability, and budget controls

One agent for your entire SDLC. Right inside Slack.

👉 Get started


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions

Copy link
Copy Markdown

Summary

Tests 📝 Passed ✅ Failed ❌ Skipped ⏭️ Other ❓ Flaky 🍂 Duration ⏱️
2350 2350 0 0 0 0 1ms

Test Results

passed 2350 passed

Details

tests 2350 tests
clock 36.4s
tool nunit
build CI - Build & Test arrow-right build-and-test link #1102
pull-request feat(input): 新增统一输入抽象与Godot集成 link #346

Insights

Average Tests per Run Total Flaky Tests Total Failed Slowest Test (p95)
2350 0 0 3.7s

build-and-test: Run #1102

Tests 📝 Passed ✅ Failed ❌ Skipped ⏭️ Pending ⏳ Other ❓ Flaky 🍂 Duration ⏱️
2350 2350 0 0 0 0 0 36.4s

🎉 All tests passed!

Slowest Tests

Test 📝 Results 📊 Duration (avg) ⏱️ Duration (p95) ⏱️
CreateStream_Should_ResolveCqrsRuntime_OnlyOnce_When_AccessedConcurrently 1 3.7s 3.7s
Does_Not_Report_When_FieldInjectedModel_Is_Registered 1 2.1s 2.1s
Generates_Scene_Behavior_Boilerplate 1 1.8s 1.8s
CleanupDuringAcquire_Should_NotCauseRaceCondition 1 1.1s 1.1s
Append_ShouldNotBlock 1 1.0s 1.0s
Context_Caching_Should_Improve_Performance 1 781ms 781ms
PendingCount_ShouldReflectQueuedEntries 1 501ms 501ms
Cleanup_Should_NotRemoveActiveLocks 1 405ms 405ms
Cleanup_Should_RemoveUnusedLocks 1 401ms 401ms
Generates_Precise_Assembly_Type_Lookups_For_Inaccessible_External_Generic_Definitions_With_Visible_Type_Arguments 1 294ms 294ms

🎉 No failed tests in this run. | 🍂 No flaky tests in this run.

Github Test Reporter by CTRF 💚

@github-actions

github-actions Bot commented May 10, 2026

Copy link
Copy Markdown

⚠️MegaLinter analysis: Success with warnings

Descriptor Linter Files Fixed Errors Warnings Elapsed time
⚠️ CSHARP dotnet-format yes 1 no 4.93s
✅ REPOSITORY gitleaks yes no no 8.27s
✅ REPOSITORY trufflehog yes no no 7.08s

Detailed Issues

⚠️ CSHARP / dotnet-format - 1 error
Welcome to .NET 9.0!
---------------------
SDK Version: 9.0.114

----------------
Installed an ASP.NET Core HTTPS development certificate.
To trust the certificate, run 'dotnet dev-certs https --trust'
Learn about HTTPS: https://aka.ms/dotnet-https

----------------
Write your first app: https://aka.ms/dotnet-hello-world
Find out what's new: https://aka.ms/dotnet-whats-new
Explore documentation: https://aka.ms/dotnet-docs
Report issues and find source on GitHub: https://github.com/dotnet/core
Use 'dotnet --help' to see available commands or visit: https://aka.ms/dotnet-cli
--------------------------------------------------------------------------------------
Unhandled exception: System.Exception: Restore operation failed.
   at Microsoft.CodeAnalysis.Tools.CodeFormatter.OpenMSBuildWorkspaceAsync(String solutionOrProjectPath, WorkspaceType workspaceType, Boolean noRestore, Boolean requiresSemantics, String binaryLogPath, Boolean logWorkspaceWarnings, ILogger logger, CancellationToken cancellationToken)
   at Microsoft.CodeAnalysis.Tools.CodeFormatter.FormatWorkspaceAsync(FormatOptions formatOptions, ILogger logger, CancellationToken cancellationToken, String binaryLogPath)
   at Microsoft.CodeAnalysis.Tools.FormatCommandCommon.FormatAsync(FormatOptions formatOptions, ILogger`1 logger, CancellationToken cancellationToken)
   at Microsoft.CodeAnalysis.Tools.Commands.RootFormatCommand.FormatCommandDefaultHandler.InvokeAsync(ParseResult parseResult, CancellationToken cancellationToken)
   at System.CommandLine.Invocation.InvocationPipeline.InvokeAsync(ParseResult parseResult, CancellationToken cancellationToken)

See detailed reports in MegaLinter artifacts
Set VALIDATE_ALL_CODEBASE: true in mega-linter.yml to validate all sources, not only the diff

MegaLinter is graciously provided by OX Security
Show us your support by starring ⭐ the repository

@greptile-apps

greptile-apps Bot commented May 10, 2026

Copy link
Copy Markdown

Greptile Summary

This PR introduces the unified input abstraction layer for GFramework, covering binding storage, device tracking, UI dispatch, and a Godot InputMap adapter — all new code with no changes to existing modules.

  • Abstractions (GFramework.Game.Abstractions/Input/): New DTOs and interfaces define the engine-agnostic contract with thorough XML docs and nullable annotations throughout.
  • Game-layer implementations (GFramework.Game/Input/): InputBindingStore delivers clear-and-replace ImportSnapshot, conflict-swap SetPrimaryBinding, and default-restore ResetAll; thread-safety assumptions are explicitly documented in remarks.
  • Godot adapter (GFramework.Godot/Input/): GodotInputBindingStore re-syncs from the live InputMap before every public call and correctly handles absent-action clearing in ImportSnapshot; GodotInputBindingCodec provides round-trip conversion between InputEvent and InputBindingDescriptor.

Confidence Score: 5/5

All new code with no modifications to existing modules; the core binding semantics and Godot adapter are correctly implemented.

The implementation is self-contained, all contracts are correctly honoured, and the previously-flagged ImportSnapshot partial-merge issue has been resolved. Only minor style and test-coverage gaps remain.

Test files (InputBindingStoreTests.cs, GodotInputBindingStoreTests.cs) are missing coverage for ImportSnapshot and ResetAction paths; GodotInputBindingCodec.cs uses a nullable suppression that can be cleaned up.

Important Files Changed

Filename Overview
GFramework.Game/Input/InputBindingStore.cs Correct in-memory implementation with clear/replace ImportSnapshot, conflict-swap SetPrimaryBinding, and thread-safety disclaimer in remarks.
GFramework.Godot/Input/GodotInputBindingStore.cs Godot adapter that now correctly handles the full-replace ImportSnapshot contract; every public call reloads from the backend first.
GFramework.Godot/Input/GodotInputBindingCodec.cs Bidirectional codec is well-structured; the TryCreateBinding out parameter uses a null-forgiving suppression (null!) that could be resolved by declaring it as nullable.
GFramework.Godot/Input/GodotInputMapBackend.cs Correctly captures defaults at construction, restores via SetBindings (which handles missing actions), and erases non-default actions on reset.
GFramework.Game.Tests/Input/InputBindingStoreTests.cs Covers SetPrimaryBinding swap, ResetAll, and GetBindings; ImportSnapshot and ResetAction paths are not tested for InputBindingStore directly.
GFramework.Godot.Tests/Input/GodotInputBindingStoreTests.cs Good FakeInputMapBackend design; covers ImportSnapshot, SetPrimaryBinding swap, and ResetAll; ResetAction on GodotInputBindingStore is not covered.

Sequence Diagram

sequenceDiagram
    participant Host as Godot Host
    participant GIS as GodotInputBindingStore
    participant State as InputBindingStore
    participant Backend as IGodotInputMapBackend
    participant InputMap as Godot InputMap

    Note over GIS,InputMap: Construction
    GIS->>Backend: GetActionNames()
    Backend->>InputMap: InputMap.GetActions()
    InputMap-->>Backend: actions[]
    GIS->>Backend: GetBindings(each action)
    Backend->>InputMap: InputMap.ActionGetEvents()
    GIS->>GodotInputBindingCodec: TryCreateBinding(inputEvent)
    GodotInputBindingCodec-->>GIS: InputBindingDescriptor
    GIS->>State: new InputBindingStore(snapshot)

    Note over GIS,InputMap: SetPrimaryBinding
    Host->>GIS: SetPrimaryBinding(action, binding)
    GIS->>Backend: ReloadFromBackend
    GIS->>State: SetPrimaryBinding(action, binding)
    GIS->>State: ExportSnapshot()
    State-->>GIS: snapshot
    GIS->>Backend: SetBindings(each action)
    Backend->>InputMap: ActionEraseEvents + ActionAddEvent

    Note over GIS,InputMap: ImportSnapshot
    Host->>GIS: ImportSnapshot(snapshot)
    GIS->>Backend: ReloadFromBackend
    GIS->>State: ExportSnapshot to compute removedActions
    GIS->>Backend: SetBindings(removedAction, [])
    GIS->>Backend: SetBindings(each snapshot action)
    GIS->>Backend: ReloadFromBackend final sync

    Note over GIS,InputMap: ResetAll
    Host->>GIS: ResetAll()
    GIS->>Backend: ResetAll()
    Backend->>InputMap: EraseAction or ActionEraseEvents+AddEvent
    GIS->>Backend: ReloadFromBackend
Loading
Prompt To Fix All With AI
Fix the following 3 code review issues. Work through them one at a time, proposing concise fixes.

---

### Issue 1 of 3
GFramework.Game.Tests/Input/InputBindingStoreTests.cs:13-14
**Missing test coverage for `ImportSnapshot` and `ResetAction` on `InputBindingStore`**

AGENTS.md requires that "when a public API defines multiple contract branches, tests MUST cover the meaningful variants." `InputBindingStore` exposes six public methods; only three are exercised here (`SetPrimaryBinding`, `ResetAll`, `GetBindings`). Both `ImportSnapshot` (clear-and-replace semantics) and `ResetAction` (single-action rollback) have distinct internal paths that should be independently verified. The same gap exists in `GodotInputBindingStoreTests`, where `ResetAction` on the `GodotInputBindingStore` is never called.

### Issue 2 of 3
GFramework.Godot/Input/GodotInputBindingCodec.cs:20
AGENTS.md requires null-safe code that respects nullable annotations instead of suppressing warnings. The null-forgiving operator on the `out` parameter is technically safe here because callers check the `bool` return value, but it bypasses the compiler's nullability flow. Declaring the out parameter as `InputBindingDescriptor?` makes the contract explicit and avoids the suppression entirely.

```suggestion
    public static bool TryCreateBinding(InputEvent inputEvent, out InputBindingDescriptor? binding)
```

### Issue 3 of 3
GFramework.Godot/Input/GodotInputBindingCodec.cs:57-59
When the `out` parameter is typed as nullable, the null-forgiving suppression on the default branch can be removed cleanly.

```suggestion
            default:
                binding = null;
                return false;
```

Reviews (3): Last reviewed commit: "fix(input): 修复输入绑定重置与审查遗留问题" | Re-trigger Greptile

Comment thread GFramework.Godot/Input/GodotInputBindingStore.cs
Comment thread GFramework.Godot/Input/GodotInputBindingCodec.cs
Comment thread GFramework.Godot/Input/GodotInputMapBackend.cs
Comment thread GFramework.Game/Input/InputBindingStore.cs

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 7

🧹 Nitpick comments (6)
GFramework.Game.Abstractions/Input/InputBindingSnapshot.cs (1)

9-23: ⚡ Quick win

建议考虑使用 record 类型

InputBindingSnapshot 是可持久化快照的值对象,表示整个绑定配置的不可变视图。建议改为 record 类型以获得值语义,便于快照比较和序列化场景。

♻️ 建议的 record 重构
 /// <summary>
 ///     描述一组动作绑定的可持久化快照。
 /// </summary>
-public sealed class InputBindingSnapshot
+public sealed record InputBindingSnapshot
 {
-    /// <summary>
-    ///     初始化一个输入绑定快照。
-    /// </summary>
-    /// <param name="actions">动作绑定集合。</param>
     public InputBindingSnapshot(IReadOnlyList<InputActionBinding> actions)
     {
         Actions = actions ?? Array.Empty<InputActionBinding>();
     }
 
-    /// <summary>
-    ///     获取动作绑定集合。
-    /// </summary>
-    public IReadOnlyList<InputActionBinding> Actions { get; }
+    public IReadOnlyList<InputActionBinding> Actions { get; init; }
 }

注意:record 仍需保留 XML 文档注释。如果快照会被序列化(例如保存到配置文件),record 的 ToString() 输出也会更便于调试。

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@GFramework.Game.Abstractions/Input/InputBindingSnapshot.cs` around lines 9 -
23, Replace the class InputBindingSnapshot with a record to give it value
semantics: change the declaration to a record type named InputBindingSnapshot
while preserving the existing XML documentation comments; ensure the Actions
property remains an IReadOnlyList<InputActionBinding> and that the constructor
logic (or primary constructor) still defaults null to
Array.Empty<InputActionBinding>() so existing behavior and immutability are
preserved; keep the public API (type name and property) unchanged so comparisons
and serialization benefit from record semantics.
GFramework.Godot/Input/IGodotInputMapBackend.cs (1)

11-43: 💤 Low value

接口契约清晰,建议明确前置条件

接口方法的参数和返回值类型合理,使用 IReadOnlyList 保持了不可变性契约。作为可选改进,建议在 XML 文档中明确关键方法的前置条件(例如 actionName 不能为 null),以便实现者和调用者了解验证责任归属。

📝 建议的文档增强示例
 /// <summary>
 ///     获取指定动作的框架绑定描述集合。
 /// </summary>
-/// <param name="actionName">动作名称。</param>
+/// <param name="actionName">动作名称,不能为 <see langword="null" />。</param>
 /// <returns>框架绑定描述集合。</returns>
+/// <exception cref="ArgumentNullException">当 <paramref name="actionName" /> 为 <see langword="null" /> 时抛出。</exception>
 IReadOnlyList<InputBindingDescriptor> GetBindings(string actionName);

类似地为 SetBindingsResetAction 等方法添加前置条件说明。

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@GFramework.Godot/Input/IGodotInputMapBackend.cs` around lines 11 - 43, Add
clear precondition docs to the interface: state that actionName for GetBindings,
SetBindings, ResetAction must be non-null and non-empty and that SetBindings'
bindings parameter must be non-null (and may be empty) and that GetActionNames/
GetBindings return IReadOnlyList that will never be null; also specify whether
implementations should throw ArgumentNullException/ArgumentException on
violation or silently ignore—e.g., document to throw ArgumentNullException for
null actionName and ArgumentException for empty names, and ArgumentNullException
for null bindings in SetBindings. Update the XML comments for GetBindings,
SetBindings, ResetAction, and ResetAll to include these precondition sentences
and the expected exceptions so implementers and callers know validation
responsibility.
GFramework.Game.Abstractions/Input/InputDeviceContext.cs (1)

9-25: ⚡ Quick win

建议考虑使用 record 类型

InputDeviceContext 是一个不可变的值对象,包含设备上下文快照数据。考虑将其改为 record 类型以获得内置的值语义(EqualsGetHashCodeToString),这在设备上下文比较或调试时会更便利。

♻️ 建议的 record 重构
 /// <summary>
 ///     描述当前活跃输入设备上下文。
 /// </summary>
-public sealed class InputDeviceContext
+public sealed record InputDeviceContext
 {
-    /// <summary>
-    ///     初始化一个输入设备上下文。
-    /// </summary>
-    /// <param name="deviceKind">当前设备族。</param>
-    /// <param name="deviceIndex">设备索引;未知时为 <see langword="null" />。</param>
-    /// <param name="deviceName">宿主归一化后的设备名称。</param>
-    public InputDeviceContext(
+    public InputDeviceContext(
         InputDeviceKind deviceKind,
         int? deviceIndex = null,
         string? deviceName = null)
     {
         DeviceKind = deviceKind;
         DeviceIndex = deviceIndex;
         DeviceName = deviceName ?? string.Empty;
     }
 
-    /// <summary>
-    ///     获取当前设备族。
-    /// </summary>
-    public InputDeviceKind DeviceKind { get; }
+    public InputDeviceKind DeviceKind { get; init; }
 
-    /// <summary>
-    ///     获取当前设备索引。
-    /// </summary>
-    public int? DeviceIndex { get; }
+    public int? DeviceIndex { get; init; }
 
-    /// <summary>
-    ///     获取宿主归一化后的设备名称。
-    /// </summary>
-    public string DeviceName { get; }
+    public string DeviceName { get; init; }
 }

注意:改为 record 后仍需保留 XML 文档注释(record 的属性和构造函数参数),以符合编码规范。

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@GFramework.Game.Abstractions/Input/InputDeviceContext.cs` around lines 9 -
25, InputDeviceContext is an immutable value object so change the class to a
record to get value semantics; replace the sealed class declaration with a
record (e.g., record InputDeviceContext) and expose the same data via init-only
properties or a positional record matching the existing constructor parameters
(DeviceKind, int? DeviceIndex, string? DeviceName) while preserving the XML
documentation comments for the constructor/parameters and retaining the
DeviceKind, DeviceIndex and DeviceName identifiers and null-handling (DeviceName
defaulting to string.Empty) so Equals/GetHashCode/ToString behave as value
semantics.
GFramework.Game.Abstractions/Input/InputBindingDescriptor.cs (1)

13-41: ⚡ Quick win

建议考虑使用 record 类型

InputBindingDescriptor 是不可变的数据传输对象,包含绑定描述快照。与 InputDeviceContext 类似,建议改为 record 类型以获得值语义,便于相等性比较和调试输出。

♻️ 建议的 record 重构
 /// <summary>
 ///     描述一个框架无关的动作绑定。
 /// </summary>
 /// <remarks>
 ///     该模型是运行时输入系统与宿主适配层之间的稳定交换格式。
 ///     宿主层负责把原生输入事件转成此描述,抽象层和默认运行时只根据这些字段做查询、冲突检测和持久化。
 /// </remarks>
-public sealed class InputBindingDescriptor
+public sealed record InputBindingDescriptor
 {
-    /// <summary>
-    ///     初始化一个动作绑定描述。
-    /// </summary>
-    /// <param name="deviceKind">设备族。</param>
-    /// <param name="bindingKind">绑定类型。</param>
-    /// <param name="code">宿主无关的物理码值。</param>
-    /// <param name="displayName">用于设置界面展示的名称。</param>
-    /// <param name="axisDirection">轴向方向;非轴向绑定时为 <see langword="null" />。</param>
-    /// <exception cref="ArgumentException">当 <paramref name="code" /> 为空时抛出。</exception>
     public InputBindingDescriptor(
         InputDeviceKind deviceKind,
         InputBindingKind bindingKind,
         string code,
         string displayName,
         float? axisDirection = null)
     {
         if (string.IsNullOrWhiteSpace(code))
         {
             throw new ArgumentException("Binding code cannot be null or whitespace.", nameof(code));
         }
 
         DeviceKind = deviceKind;
         BindingKind = bindingKind;
         Code = code;
         DisplayName = displayName ?? string.Empty;
         AxisDirection = axisDirection;
     }
 
-    /// <summary>
-    ///     获取设备族。
-    /// </summary>
-    public InputDeviceKind DeviceKind { get; }
+    public InputDeviceKind DeviceKind { get; init; }
 
-    /// <summary>
-    ///     获取绑定类型。
-    /// </summary>
-    public InputBindingKind BindingKind { get; }
+    public InputBindingKind BindingKind { get; init; }
 
-    /// <summary>
-    ///     获取宿主无关的物理码值。
-    /// </summary>
-    public string Code { get; }
+    public string Code { get; init; }
 
-    /// <summary>
-    ///     获取用于展示的标签。
-    /// </summary>
-    public string DisplayName { get; }
+    public string DisplayName { get; init; }
 
-    /// <summary>
-    ///     获取轴向方向。
-    /// </summary>
-    public float? AxisDirection { get; }
+    public float? AxisDirection { get; init; }
 }

注意:record 仍需保留 XML 文档注释以符合编码规范。

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@GFramework.Game.Abstractions/Input/InputBindingDescriptor.cs` around lines 13
- 41, Convert the immutable data class InputBindingDescriptor into a record with
the same public API: change InputBindingDescriptor to a public sealed record
that exposes DeviceKind, BindingKind, Code, DisplayName and AxisDirection as
init-only properties (or positional parameters) while preserving the constructor
validation that throws ArgumentException when Code is null/whitespace, preserve
the default DisplayName -> string.Empty and nullable AxisDirection behavior, and
keep the existing XML doc comments; ensure equality/value semantics and ToString
come from the record type and that any callers using the old constructor still
get the validation logic.
GFramework.Game.Abstractions/Input/InputActionBinding.cs (1)

9-26: ⚡ Quick win

建议考虑使用 record 类型

InputActionBinding 是不可变快照类型,表示动作及其绑定的只读视图。建议改为 record 以获得值语义,与其他快照类型(如 InputBindingSnapshot)保持一致的设计模式。

♻️ 建议的 record 重构
 /// <summary>
 ///     描述一个逻辑动作当前持有的绑定集合。
 /// </summary>
-public sealed class InputActionBinding
+public sealed record InputActionBinding
 {
-    /// <summary>
-    ///     初始化一个动作绑定快照。
-    /// </summary>
-    /// <param name="actionName">动作名称。</param>
-    /// <param name="bindings">当前绑定列表。</param>
-    /// <exception cref="ArgumentException">当 <paramref name="actionName" /> 为空时抛出。</exception>
     public InputActionBinding(string actionName, IReadOnlyList<InputBindingDescriptor> bindings)
     {
         if (string.IsNullOrWhiteSpace(actionName))
         {
             throw new ArgumentException("Action name cannot be null or whitespace.", nameof(actionName));
         }
 
         ActionName = actionName;
         Bindings = bindings ?? Array.Empty<InputBindingDescriptor>();
     }
 
-    /// <summary>
-    ///     获取动作名称。
-    /// </summary>
-    public string ActionName { get; }
+    public string ActionName { get; init; }
 
-    /// <summary>
-    ///     获取当前绑定列表。
-    /// </summary>
-    public IReadOnlyList<InputBindingDescriptor> Bindings { get; }
+    public IReadOnlyList<InputBindingDescriptor> Bindings { get; init; }
 }

注意:record 仍需保留 XML 文档注释。

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@GFramework.Game.Abstractions/Input/InputActionBinding.cs` around lines 9 -
26, Convert the immutable snapshot class InputActionBinding to a record to get
value semantics consistent with other snapshots (e.g., InputBindingSnapshot):
change the declaration from class to a record (e.g., public sealed record
InputActionBinding) and keep the existing constructor logic that validates
actionName and assigns Bindings (falling back to
Array.Empty<InputBindingDescriptor>() when null); preserve the XML doc comments
for the type and parameters, and ensure the public members ActionName and
Bindings remain available (init-only or positional record properties) so
existing callers continue to work.
ai-plan/public/input-system-godot-integration/traces/input-system-godot-integration-trace.md (1)

7-8: ⚡ Quick win

收敛 trace 中的环境路径细节

这里记录本地 worktree 目录名对恢复入口帮助不大,且会把环境细节带进公开历史。建议改为“分支名 + PR 编号”这类稳定标识。

As per coding guidelines "Never write ... machine usernames, home-directory paths ... or other sensitive environment details into any ai-plan/** file" and "Never record absolute file-system paths in ai-plan/**; use repository-relative paths, branch names, PR numbers...".

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@ai-plan/public/input-system-godot-integration/traces/input-system-godot-integration-trace.md`
around lines 7 - 8, The trace includes a local worktree directory name
(GFramework-WorkTree/GFramework-input-system-godot-integration); replace that
environment-specific path with a stable identifier composed of the branch name
(feat/input-system-godot-integration) and the PR number (e.g.,
"feat/input-system-godot-integration#NNN") in the file
ai-plan/public/input-system-godot-integration/traces/input-system-godot-integration-trace.md
so the record uses repository-relative, non-sensitive identifiers instead of
machine-specific directories.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@GFramework.Game.Abstractions/README.md`:
- Line 180: The README currently lists "Input/" as an entry point but doesn't
include the corresponding docs link; update the "对应文档入口" section in
GFramework.Game.Abstractions/README.md to add an entry pointing to
docs/zh-CN/game/input.md so the module README lists the matching docs. Make sure
the "Input/" row or bullet references docs/zh-CN/game/input.md alongside the
existing symbols (`Input/`, `InputBindingDescriptor`, `IInputBindingStore`,
`IInputDeviceTracker`, `IUiInputDispatcher`) so navigation is complete.

In `@GFramework.Game/Input/InputBindingStore.cs`:
- Around line 31-35: GetBindings currently calls GetOrCreateBindings which
implicitly creates an entry during a read and causes empty entries to be
exported by ExportSnapshot; change GetBindings so it does a read-only lookup
(e.g., use the underlying dictionary.TryGetValue or a new TryGetBindings helper)
instead of calling GetOrCreateBindings, and return an InputActionBinding with an
empty array when no bindings exist. Ensure you only reference GetBindings and
InputActionBinding (and ExportSnapshot semantics remain intact) and do not
mutate the store during this method.

In `@GFramework.Game/Input/InputDeviceTracker.cs`:
- Around line 22-31: The XML docs for Update and CurrentDevice lack
thread-safety guidance; either document that Update must be called only from the
host/input thread (e.g., Godot's main/input event thread) by adding a <remarks>
to the Update method and to CurrentDevice explaining the required calling
thread, or make CurrentDevice a volatile field/property to ensure cross-thread
visibility and document that choice in the XML docs (mentioning that volatile
provides write-read visibility but does not provide higher-level
synchronization). Update the XML comments on the Update method and the
CurrentDevice member to state which approach you chose and the expected
synchronization semantics so callers know how to safely access them.

In `@GFramework.Game/Input/UiInputDispatcher.cs`:
- Around line 17-26: The constructor UiInputDispatcher(IUiInputActionMap
actionMap, IUiRouter router) performs null checks and throws
ArgumentNullException for actionMap and router but the XML doc lacks <exception>
entries; update the constructor's XML documentation to include two <exception
cref="System.ArgumentNullException"> tags describing when actionMap and router
are null (reference the parameter names in the descriptions) so the thrown
exceptions are documented.

In `@GFramework.Game/README.md`:
- Around line 162-177: README.md is missing a top-level link to the new Input
subsystem; add an entry to the README's main "文档入口" list pointing to the 输入系统
docs at ../docs/zh-CN/game/input.md so the module README and docs entry points
are consistent. Locate the README's summary/list of subsystem links and append
or insert a line referencing "输入系统 (Input)" that corresponds to the Input folder
and symbols InputBindingStore, InputDeviceTracker, UiInputActionMap,
UiInputDispatcher to satisfy the rule that a module README must reference its
docs/zh-CN entry.

In `@GFramework.Godot/Input/GodotInputBindingStore.cs`:
- Around line 59-68: ImportSnapshot currently only updates actions present in
the snapshot and leaves any old backend bindings intact; change ImportSnapshot
(which calls ReloadFromBackend and ApplyActionBindings) to perform a
snapshot-level replace by: after reloading backend, enumerate the current stored
action IDs, compute the set difference with snapshot.Actions, and remove/clear
bindings for any actions not present in the snapshot (use or add a
backend-facing helper such as RemoveActionBindings/RemoveAction or
ClearBindingsForAction as appropriate), then apply bindings for each action in
snapshot via ApplyActionBindings so the store exactly matches the snapshot.

In `@GFramework.Godot/Input/GodotInputMapBackend.cs`:
- Around line 33-37: GetBindings currently calls InputMap.ActionGetEvents
without validating the incoming actionName; update GetBindings to validate the
parameter (null/empty) and check existence with InputMap.HasAction(actionName)
and if the action does not exist return an empty
IReadOnlyList<InputBindingDescriptor> immediately, avoiding calling
InputMap.ActionGetEvents or passing invalid input to host APIs; locate this
logic in the GetBindings method and mirror the same parameter checks used in
SetBindings/ResetAction.

---

Nitpick comments:
In
`@ai-plan/public/input-system-godot-integration/traces/input-system-godot-integration-trace.md`:
- Around line 7-8: The trace includes a local worktree directory name
(GFramework-WorkTree/GFramework-input-system-godot-integration); replace that
environment-specific path with a stable identifier composed of the branch name
(feat/input-system-godot-integration) and the PR number (e.g.,
"feat/input-system-godot-integration#NNN") in the file
ai-plan/public/input-system-godot-integration/traces/input-system-godot-integration-trace.md
so the record uses repository-relative, non-sensitive identifiers instead of
machine-specific directories.

In `@GFramework.Game.Abstractions/Input/InputActionBinding.cs`:
- Around line 9-26: Convert the immutable snapshot class InputActionBinding to a
record to get value semantics consistent with other snapshots (e.g.,
InputBindingSnapshot): change the declaration from class to a record (e.g.,
public sealed record InputActionBinding) and keep the existing constructor logic
that validates actionName and assigns Bindings (falling back to
Array.Empty<InputBindingDescriptor>() when null); preserve the XML doc comments
for the type and parameters, and ensure the public members ActionName and
Bindings remain available (init-only or positional record properties) so
existing callers continue to work.

In `@GFramework.Game.Abstractions/Input/InputBindingDescriptor.cs`:
- Around line 13-41: Convert the immutable data class InputBindingDescriptor
into a record with the same public API: change InputBindingDescriptor to a
public sealed record that exposes DeviceKind, BindingKind, Code, DisplayName and
AxisDirection as init-only properties (or positional parameters) while
preserving the constructor validation that throws ArgumentException when Code is
null/whitespace, preserve the default DisplayName -> string.Empty and nullable
AxisDirection behavior, and keep the existing XML doc comments; ensure
equality/value semantics and ToString come from the record type and that any
callers using the old constructor still get the validation logic.

In `@GFramework.Game.Abstractions/Input/InputBindingSnapshot.cs`:
- Around line 9-23: Replace the class InputBindingSnapshot with a record to give
it value semantics: change the declaration to a record type named
InputBindingSnapshot while preserving the existing XML documentation comments;
ensure the Actions property remains an IReadOnlyList<InputActionBinding> and
that the constructor logic (or primary constructor) still defaults null to
Array.Empty<InputActionBinding>() so existing behavior and immutability are
preserved; keep the public API (type name and property) unchanged so comparisons
and serialization benefit from record semantics.

In `@GFramework.Game.Abstractions/Input/InputDeviceContext.cs`:
- Around line 9-25: InputDeviceContext is an immutable value object so change
the class to a record to get value semantics; replace the sealed class
declaration with a record (e.g., record InputDeviceContext) and expose the same
data via init-only properties or a positional record matching the existing
constructor parameters (DeviceKind, int? DeviceIndex, string? DeviceName) while
preserving the XML documentation comments for the constructor/parameters and
retaining the DeviceKind, DeviceIndex and DeviceName identifiers and
null-handling (DeviceName defaulting to string.Empty) so
Equals/GetHashCode/ToString behave as value semantics.

In `@GFramework.Godot/Input/IGodotInputMapBackend.cs`:
- Around line 11-43: Add clear precondition docs to the interface: state that
actionName for GetBindings, SetBindings, ResetAction must be non-null and
non-empty and that SetBindings' bindings parameter must be non-null (and may be
empty) and that GetActionNames/ GetBindings return IReadOnlyList that will never
be null; also specify whether implementations should throw
ArgumentNullException/ArgumentException on violation or silently ignore—e.g.,
document to throw ArgumentNullException for null actionName and
ArgumentException for empty names, and ArgumentNullException for null bindings
in SetBindings. Update the XML comments for GetBindings, SetBindings,
ResetAction, and ResetAll to include these precondition sentences and the
expected exceptions so implementers and callers know validation responsibility.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 142798c2-190a-4d24-96b9-8c10574177cd

📥 Commits

Reviewing files that changed from the base of the PR and between 699d0b4 and ebbef32.

📒 Files selected for processing (32)
  • GFramework.Game.Abstractions/Input/IInputBindingStore.cs
  • GFramework.Game.Abstractions/Input/IInputDeviceTracker.cs
  • GFramework.Game.Abstractions/Input/IUiInputActionMap.cs
  • GFramework.Game.Abstractions/Input/IUiInputDispatcher.cs
  • GFramework.Game.Abstractions/Input/InputActionBinding.cs
  • GFramework.Game.Abstractions/Input/InputBindingDescriptor.cs
  • GFramework.Game.Abstractions/Input/InputBindingKind.cs
  • GFramework.Game.Abstractions/Input/InputBindingSnapshot.cs
  • GFramework.Game.Abstractions/Input/InputDeviceContext.cs
  • GFramework.Game.Abstractions/Input/InputDeviceKind.cs
  • GFramework.Game.Abstractions/README.md
  • GFramework.Game.Tests/Input/InputBindingStoreTests.cs
  • GFramework.Game.Tests/Input/UiInputDispatcherTests.cs
  • GFramework.Game/Input/InputBindingStore.cs
  • GFramework.Game/Input/InputDeviceTracker.cs
  • GFramework.Game/Input/UiInputActionMap.cs
  • GFramework.Game/Input/UiInputDispatcher.cs
  • GFramework.Game/README.md
  • GFramework.Godot.Tests/Input/GodotInputBindingStoreTests.cs
  • GFramework.Godot/Input/GodotInputBindingCodec.cs
  • GFramework.Godot/Input/GodotInputBindingStore.cs
  • GFramework.Godot/Input/GodotInputMapBackend.cs
  • GFramework.Godot/Input/IGodotInputMapBackend.cs
  • GFramework.Godot/README.md
  • ai-plan/public/README.md
  • ai-plan/public/input-system-godot-integration/todos/input-system-godot-integration-tracking.md
  • ai-plan/public/input-system-godot-integration/traces/input-system-godot-integration-trace.md
  • docs/zh-CN/game/index.md
  • docs/zh-CN/game/input.md
  • docs/zh-CN/godot/index.md
  • docs/zh-CN/godot/input.md
  • docs/zh-CN/tutorials/godot-integration.md
📜 Review details
⏰ Context from checks skipped due to timeout of 900000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: Code Quality & Security
  • GitHub Check: Build and Test
  • GitHub Check: Analyze (C#)
🧰 Additional context used
📓 Path-based instructions (13)
**/*Abstractions/**/*.cs

📄 CodeRabbit inference engine (CLAUDE.md)

Abstractions projects should only contain interfaces and contract definitions without any runtime implementation logic

Files:

  • GFramework.Game.Abstractions/Input/InputDeviceKind.cs
  • GFramework.Game.Abstractions/Input/IUiInputDispatcher.cs
  • GFramework.Game.Abstractions/Input/IInputBindingStore.cs
  • GFramework.Game.Abstractions/Input/InputBindingDescriptor.cs
  • GFramework.Game.Abstractions/Input/InputBindingSnapshot.cs
  • GFramework.Game.Abstractions/Input/IInputDeviceTracker.cs
  • GFramework.Game.Abstractions/Input/InputBindingKind.cs
  • GFramework.Game.Abstractions/Input/IUiInputActionMap.cs
  • GFramework.Game.Abstractions/Input/InputDeviceContext.cs
  • GFramework.Game.Abstractions/Input/InputActionBinding.cs
**/*.cs

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.cs: Apply [Log] attribute for automatic logging field and logging helper method generation
Apply [Priority] attribute for automatic priority comparison implementation generation
Apply [GenerateEnumExtensions] attribute to generate enumeration extension capabilities
Apply [ContextAware] attribute to automatically implement IContextAware boilerplate logic

**/*.cs: All public, protected, and internal types and members MUST include XML documentation comments (///)
XML documentation comments MUST use <summary>, <param>, <returns>, <exception>, and <remarks> where applicable, explaining intent, contract, and usage constraints instead of restating syntax
If a member participates in lifecycle, threading, registration, or disposal behavior, document that behavior explicitly in XML documentation
Add inline comments for non-trivial logic, concurrency or threading behavior, performance-sensitive paths, workarounds and compatibility constraints, edge cases, registration order, lifecycle sequencing, and generated code assumptions
Avoid obvious comments such as // increment i
Methods with non-trivial logic MUST document: The core idea, Key decisions, and Edge case handling, if any
Comments MUST NOT be trivial, redundant, or misleading. Prefer explaining why and when, not just what. Code should remain understandable without requiring external context. Prefer slightly more explanation over too little for framework code
Do not rely on implicit imports. Declare every required using explicitly
Write null-safe code that respects nullable annotations instead of suppressing warnings by default
Use the namespace pattern GFramework.{Module}.{Feature} with PascalCase segments
Follow standard C# naming: Types, methods, properties, events, and constants use PascalCase; Interfaces use I prefix; Parameters and locals use camelCase; Private fields use _camelCase
Use 4 spaces for indentation. Do not use tabs
Use Allman braces
Keep using directives at the top...

Files:

  • GFramework.Game.Abstractions/Input/InputDeviceKind.cs
  • GFramework.Game.Abstractions/Input/IUiInputDispatcher.cs
  • GFramework.Game/Input/UiInputActionMap.cs
  • GFramework.Game/Input/InputDeviceTracker.cs
  • GFramework.Game.Abstractions/Input/IInputBindingStore.cs
  • GFramework.Game.Abstractions/Input/InputBindingDescriptor.cs
  • GFramework.Game/Input/UiInputDispatcher.cs
  • GFramework.Game.Abstractions/Input/InputBindingSnapshot.cs
  • GFramework.Godot.Tests/Input/GodotInputBindingStoreTests.cs
  • GFramework.Game.Abstractions/Input/IInputDeviceTracker.cs
  • GFramework.Game.Abstractions/Input/InputBindingKind.cs
  • GFramework.Game.Abstractions/Input/IUiInputActionMap.cs
  • GFramework.Game.Tests/Input/UiInputDispatcherTests.cs
  • GFramework.Game.Abstractions/Input/InputDeviceContext.cs
  • GFramework.Game.Abstractions/Input/InputActionBinding.cs
  • GFramework.Godot/Input/GodotInputBindingCodec.cs
  • GFramework.Game.Tests/Input/InputBindingStoreTests.cs
  • GFramework.Godot/Input/IGodotInputMapBackend.cs
  • GFramework.Godot/Input/GodotInputMapBackend.cs
  • GFramework.Godot/Input/GodotInputBindingStore.cs
  • GFramework.Game/Input/InputBindingStore.cs
**/README.md

📄 CodeRabbit inference engine (AGENTS.md)

**/README.md: Use the canonical filename README.md. Do not introduce new ReadMe.md or other filename variants
A module README MUST describe: the module's purpose, the relationship to adjacent runtime, abstractions, or generator packages, the major subdirectories or subsystems the reader is expected to use, the minimum adoption path, and the corresponding docs/zh-CN/ entry points
If a module's responsibilities, setup, public API surface, generator inputs, or adoption path change, update that module's README.md in the same change

Files:

  • ai-plan/public/README.md
  • GFramework.Game.Abstractions/README.md
  • GFramework.Game/README.md
  • GFramework.Godot/README.md
ai-plan/public/**

📄 CodeRabbit inference engine (AGENTS.md)

ai-plan/public/**: Contributors MUST keep committed ai-plan/public/** content safe to publish in Git history
Active tracking and trace files are recovery entrypoints, not append-only changelogs. They MUST stay concise enough for boot to locate the current recovery point quickly
When completed and validated stages begin to accumulate, contributors MUST archive their detailed history out of the active todos/ and traces/ entry files in the same change. Keep only the current recovery point, active facts, active risks, immediate next step, and pointers to the relevant archive files in the default boot path
When a topic is fully complete, move the entire topic directory under ai-plan/public/archive/<topic>/ and remove it from ai-plan/public/README.md in the same change
When a task spans multiple commits or is likely to exceed a single agent context window, update both the recovery document and the trace at each meaningful milestone before pausing or handing work off
If subagents are used on a complex task, the main agent MUST capture the delegated scope and any accepted findings in the active recovery document or trace before continuing implementation

Files:

  • ai-plan/public/README.md
  • ai-plan/public/input-system-godot-integration/traces/input-system-godot-integration-trace.md
  • ai-plan/public/input-system-godot-integration/todos/input-system-godot-integration-tracking.md
ai-plan/**

📄 CodeRabbit inference engine (AGENTS.md)

ai-plan/**: Never write secrets, tokens, credentials, private keys, machine usernames, home-directory paths, hostnames, IP addresses, proprietary URLs, or other sensitive environment details into any ai-plan/** file
Never record absolute file-system paths in ai-plan/**; use repository-relative paths, branch names, PR numbers, or stable document identifiers instead

Files:

  • ai-plan/public/README.md
  • ai-plan/public/input-system-godot-integration/traces/input-system-godot-integration-trace.md
  • ai-plan/public/input-system-godot-integration/todos/input-system-godot-integration-tracking.md
ai-plan/public/README.md

📄 CodeRabbit inference engine (AGENTS.md)

ai-plan/public/README.md: ai-plan/public/README.md MUST list only active topics. Do not add ai-plan/public/archive/** content to the default boot index
When a worktree-to-topic mapping changes, or when a topic becomes active/inactive, contributors MUST update ai-plan/public/README.md in the same change

Files:

  • ai-plan/public/README.md
ai-plan/public/**/traces/**

📄 CodeRabbit inference engine (AGENTS.md)

Contributors MUST maintain a matching execution trace under ai-plan/public/<topic>/traces/ for complex work. The trace should record the current date, key decisions, validation milestones, and the immediate next step

Files:

  • ai-plan/public/input-system-godot-integration/traces/input-system-godot-integration-trace.md
docs/**/*.md

📄 CodeRabbit inference engine (CLAUDE.md)

Documentation should be organized with Chinese content in docs/zh-CN/ and structured to include getting started, module-specific capabilities (Core, Game, Godot, ECS), source generator usage, tutorials, best practices, and troubleshooting

Files:

  • docs/zh-CN/tutorials/godot-integration.md
  • docs/zh-CN/game/index.md
  • docs/zh-CN/godot/input.md
  • docs/zh-CN/godot/index.md
  • docs/zh-CN/game/input.md
{README.md,docs/**}

📄 CodeRabbit inference engine (AGENTS.md)

{README.md,docs/**}: Update the relevant README.md or docs/ page when behavior, setup steps, architecture guidance, or user-facing examples change
Public documentation under README.md and docs/ MUST stay reader-facing. Do not publish governance-only content such as inventory tables, coverage baselines, review queues, batch metrics, recovery points, trace summaries, or "this still needs a later audit wave" notes
Public documentation MUST use semantic section titles and link labels. Do not surface raw filenames or paths such as README.mdgame/index.md../core/cqrs.md as reader-facing navigation text when a meaningful destination label is available
Public documentation MUST avoid rhetorical, self-referential, or AI-sounding headings and prompts. Prefer neutral labels instead of phrases like "你真正会用到的公开入口"、"先理解包关系"、"这个栏目应该回答什么" or "想看……转到……"
Public documentation MUST present limitations, suitability, and migration boundaries as adoption guidance for readers. Do not publish internal-governance or product-roadmap wording in README.md or docs/**; that material belongs in ai-plan/**

Files:

  • docs/zh-CN/tutorials/godot-integration.md
  • docs/zh-CN/game/index.md
  • docs/zh-CN/godot/input.md
  • docs/zh-CN/godot/index.md
  • docs/zh-CN/game/input.md
docs/**

📄 CodeRabbit inference engine (AGENTS.md)

docs/**: The main documentation site lives under docs/, with Chinese content under docs/zh-CN/
Keep code samples, package names, and command examples aligned with the current repository state
Prefer documenting behavior and design intent, not only API surface
When a public page references XML docs or API coverage, convert that evidence into reader-facing guidance: explain which types, namespaces, or entry points readers should inspect and why, instead of exposing audit counts or governance terminology
If an existing documentation page no longer reflects the current implementation, fixing the code without fixing the documentation is considered incomplete work
Do not rely on "the code is self-explanatory" for framework features that consumers need to adopt; write the adoption path down so future users do not need to rediscover it from source
When examples are rewritten, preserve only the parts that remain true. Delete or replace speculative examples instead of lightly editing them into another inaccurate form

Files:

  • docs/zh-CN/tutorials/godot-integration.md
  • docs/zh-CN/game/index.md
  • docs/zh-CN/godot/input.md
  • docs/zh-CN/godot/index.md
  • docs/zh-CN/game/input.md
docs/zh-CN/**

📄 CodeRabbit inference engine (AGENTS.md)

docs/zh-CN/**: When a feature is added, removed, renamed, or substantially refactored, contributors MUST update or create the corresponding user-facing integration documentation in docs/zh-CN/ in the same change
For integration-oriented features such as the AI-First config system, documentation MUST cover: project directory layout and file conventions, required project or package wiring, minimal working usage example, and migration or compatibility notes when behavior changes

Files:

  • docs/zh-CN/tutorials/godot-integration.md
  • docs/zh-CN/game/index.md
  • docs/zh-CN/godot/input.md
  • docs/zh-CN/godot/index.md
  • docs/zh-CN/game/input.md
**/*.Tests/**/*.cs

📄 CodeRabbit inference engine (AGENTS.md)

**/*.Tests/**/*.cs: Mirror the source structure in test projects whenever practical
Reuse existing architecture test infrastructure when relevant: ArchitectureTestsBase<T>, SyncTestArchitecture, AsyncTestArchitecture

Files:

  • GFramework.Godot.Tests/Input/GodotInputBindingStoreTests.cs
  • GFramework.Game.Tests/Input/UiInputDispatcherTests.cs
  • GFramework.Game.Tests/Input/InputBindingStoreTests.cs
ai-plan/public/**/todos/**

📄 CodeRabbit inference engine (AGENTS.md)

ai-plan/public/**/todos/**: When working from a tracked implementation plan, contributors MUST update the corresponding tracking document under ai-plan/public/<topic>/todos/ in the same change
Tracking updates MUST reflect completed work, newly discovered issues, validation results, and the next recommended recovery point
For any multi-step refactor, migration, or cross-module task, contributors MUST create or adopt a dedicated recovery document under ai-plan/public/<topic>/todos/ before making substantive code changes
Recovery documents MUST record the current phase, the active recovery point identifier, known risks, and the next recommended resume step so another contributor or subagent can continue the work safely

Files:

  • ai-plan/public/input-system-godot-integration/todos/input-system-godot-integration-tracking.md
🧠 Learnings (1)
📚 Learning: 2026-04-06T12:45:43.921Z
Learnt from: GeWuYou
Repo: GeWuYou/GFramework PR: 190
File: GFramework.Game/Config/GameConfigBootstrap.cs:1-3
Timestamp: 2026-04-06T12:45:43.921Z
Learning: In the GeWuYou/GFramework repository, C# files may omit explicit `using System*` imports because the project-wide `GlobalUsings.cs` (referenced via manual global `using` directives) supplies common namespaces (e.g., `System`, `System.Threading`, `System.Threading.Tasks`). During code review, do not flag missing `using System...` directives in `.cs` files as long as `GlobalUsings.cs` is present/used to provide those namespaces.

Applied to files:

  • GFramework.Game.Abstractions/Input/InputDeviceKind.cs
  • GFramework.Game.Abstractions/Input/IUiInputDispatcher.cs
  • GFramework.Game/Input/UiInputActionMap.cs
  • GFramework.Game/Input/InputDeviceTracker.cs
  • GFramework.Game.Abstractions/Input/IInputBindingStore.cs
  • GFramework.Game.Abstractions/Input/InputBindingDescriptor.cs
  • GFramework.Game/Input/UiInputDispatcher.cs
  • GFramework.Game.Abstractions/Input/InputBindingSnapshot.cs
  • GFramework.Godot.Tests/Input/GodotInputBindingStoreTests.cs
  • GFramework.Game.Abstractions/Input/IInputDeviceTracker.cs
  • GFramework.Game.Abstractions/Input/InputBindingKind.cs
  • GFramework.Game.Abstractions/Input/IUiInputActionMap.cs
  • GFramework.Game.Tests/Input/UiInputDispatcherTests.cs
  • GFramework.Game.Abstractions/Input/InputDeviceContext.cs
  • GFramework.Game.Abstractions/Input/InputActionBinding.cs
  • GFramework.Godot/Input/GodotInputBindingCodec.cs
  • GFramework.Game.Tests/Input/InputBindingStoreTests.cs
  • GFramework.Godot/Input/IGodotInputMapBackend.cs
  • GFramework.Godot/Input/GodotInputMapBackend.cs
  • GFramework.Godot/Input/GodotInputBindingStore.cs
  • GFramework.Game/Input/InputBindingStore.cs
🔇 Additional comments (12)
ai-plan/public/input-system-godot-integration/todos/input-system-godot-integration-tracking.md (1)

1-49: 跟踪文档结构完整,符合恢复点规范。

该跟踪文档正确定义了恢复点编号(INPUT-GODOT-RP-001)、当前阶段、状态摘要、风险缓解措施、验证命令以及下一步行动,内容简洁且适合作为 boot 入口快速定位当前进度。验证命令使用相对路径且不包含敏感信息,符合 ai-plan 安全发布要求。

GFramework.Game.Abstractions/Input/IUiInputActionMap.cs (1)

1-21: 接口定义清晰,文档完整。

IUiInputActionMap 接口职责明确,仅定义逻辑动作名到 UI 语义动作的映射契约,符合抽象层设计原则。XML 文档包含完整的 <summary><param><returns> 标签,清楚说明了映射语义。

GFramework.Game.Abstractions/Input/InputBindingKind.cs (1)

1-36: 枚举定义合理,覆盖常见输入绑定类型。

InputBindingKind 枚举清晰定义了键盘按键、鼠标按钮、手柄按钮和手柄轴向等主要输入类型,每个成员都配有 XML 文档说明。Unknown = 0 作为默认值符合最佳实践。

GFramework.Game.Abstractions/Input/IUiInputDispatcher.cs (1)

1-18: 输入分发契约设计简洁有效。

IUiInputDispatcher 接口通过单一职责的 TryDispatch 方法定义了输入动作到 UI 路由的桥接契约,返回值语义明确(映射成功且分发成功时返回 true),XML 文档完整。

GFramework.Game.Abstractions/Input/InputDeviceKind.cs (1)

1-35: 设备族枚举设计合理,文档详尽。

InputDeviceKind 枚举定义了跨宿主的输入设备族分类,<remarks> 部分清楚说明了该抽象的设计意图(避免暴露引擎原生类型,确保上层业务依赖稳定的设备族判断),这种对设计动机的明确记录值得肯定。

ai-plan/public/README.md (1)

41-44: 公共索引更新正确,与新增主题同步。

新增的 input-system-godot-integration 活跃主题条目包含完整的目的说明、跟踪文档和追踪文档链接,同时在 Worktree 映射中正确注册了对应分支,格式与现有条目保持一致,符合 ai-plan 治理规范。

Also applies to: 62-64

GFramework.Game/Input/UiInputActionMap.cs (1)

1-40: 默认映射实现简洁高效。

UiInputActionMap 实现正确处理了空值/空白字符串输入(第 31 行),使用 StringComparer.OrdinalIgnoreCase 实现大小写不敏感匹配,并通过静态只读字典提供了合理的默认别名集(兼容 Godot ui_* 命名约定)。<remarks> 部分明确说明了可通过自定义实现扩展映射表的能力。

GFramework.Game/Input/UiInputDispatcher.cs (1)

28-37: 分发逻辑实现正确,职责清晰。

TryDispatch 方法正确实现了"映射失败时提前返回 false,映射成功时将结果转发给 UI 路由器"的桥接语义,逻辑简洁且符合单一职责原则。

GFramework.Game.Tests/Input/UiInputDispatcherTests.cs (1)

1-52: 测试覆盖合理且结构清晰

测试用例覆盖了映射成功和未知动作两种场景,使用 Assert.Multiple 提高了断言的可读性,Mock 验证逻辑正确。实现符合 NUnit 最佳实践。

GFramework.Game.Abstractions/Input/IInputDeviceTracker.cs (1)

1-15: 接口设计清晰

单一职责接口,仅公开只读的 CurrentDevice 属性,符合抽象层的设计原则。XML 文档注释充分说明了契约语义。

GFramework.Game.Abstractions/Input/InputBindingDescriptor.cs (1)

31-34: 验证逻辑正确

code 参数进行非空白验证是恰当的,因为它是绑定的核心标识符。异常类型和消息清晰明确。

GFramework.Game.Abstractions/Input/InputActionBinding.cs (1)

19-22: 验证逻辑正确

actionName 的非空白验证是必要的,确保了动作绑定始终有有效的标识符。

Comment thread GFramework.Game.Abstractions/README.md
Comment thread GFramework.Game/Input/InputBindingStore.cs
Comment thread GFramework.Game/Input/InputDeviceTracker.cs
Comment thread GFramework.Game/Input/UiInputDispatcher.cs
Comment thread GFramework.Game/README.md
Comment thread GFramework.Godot/Input/GodotInputBindingStore.cs
Comment thread GFramework.Godot/Input/GodotInputMapBackend.cs
- 修复 InputBindingStore 只读查询会污染导出快照的问题

- 修复 Godot 输入绑定导入时未清理残留动作绑定的问题

- 补充输入运行时与 Godot backend 的 XML 契约说明和 README 入口

- 更新 ai-plan 跟踪并补充针对 PR #346 的回归测试
@github-actions

Copy link
Copy Markdown

Summary

Tests 📝 Passed ✅ Failed ❌ Skipped ⏭️ Other ❓ Flaky 🍂 Duration ⏱️
2352    ↑2 2352    ↑2 0 0 0 0 39.4s    ↑3.0s

Test Results

passed 2352 passed ↑2

Details

tests 2352 tests ↑2
clock 39.4s ↑3.0s
tool nunit
build CI - Build & Test arrow-right build-and-test link #1103
pull-request feat(input): 新增统一输入抽象与Godot集成 link #346

Insights

Average Tests per Run Total Flaky Tests Total Failed Slowest Test (p95)
2351 0 0 4.6s

build-and-test: Run #1103

Tests 📝 Passed ✅ Failed ❌ Skipped ⏭️ Pending ⏳ Other ❓ Flaky 🍂 Duration ⏱️
2352 2352 0 0 0 0 0 39.4s

🎉 All tests passed!

Slowest Tests

Test 📝 Results 📊 Duration (avg) ⏱️ Duration (p95) ⏱️
CreateStream_Should_ResolveCqrsRuntime_OnlyOnce_When_AccessedConcurrently 2 4.1s 4.6s
Does_Not_Report_When_FieldInjectedModel_Is_Registered 2 2.3s 2.5s
Generates_Scene_Behavior_Boilerplate 2 1.8s 1.9s
CleanupDuringAcquire_Should_NotCauseRaceCondition 2 1.1s 1.1s
Append_ShouldNotBlock 2 1.0s 1.0s
Context_Caching_Should_Improve_Performance 2 780ms 781ms
PendingCount_ShouldReflectQueuedEntries 2 501ms 501ms
Cleanup_Should_NotRemoveActiveLocks 2 404ms 405ms
Cleanup_Should_RemoveUnusedLocks 2 401ms 401ms
Generates_Module_Install_Method_In_Attribute_Order 2 299ms 320ms

± Comparison with run #1102 at 4026ee3 | 🎉 No failed tests detected across all runs. | 🍂 No flaky tests detected across all runs. | ⏱️ Measured over 2 runs.

Github Test Reporter by CTRF 💚

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
ai-plan/public/input-system-godot-integration/todos/input-system-godot-integration-tracking.md (1)

46-47: 验证结果待补录。

第 47 行的 license-header 检查结果标记为"待本轮验证补录"。

是否需要我生成验证脚本来完成此项检查并补录结果?

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@ai-plan/public/input-system-godot-integration/todos/input-system-godot-integration-tracking.md`
around lines 46 - 47, The TODO entry shows the license-header check result as
"待本轮验证补录"—fix by running the exact command shown (`python3
scripts/license-header.py --check --paths GFramework.Game.Abstractions/README.md
GFramework.Game.Tests/Input/InputBindingStoreTests.cs
GFramework.Game/Input/InputBindingStore.cs
GFramework.Game/Input/InputDeviceTracker.cs
GFramework.Game/Input/UiInputDispatcher.cs GFramework.Game/README.md
GFramework.Godot.Tests/Input/GodotInputBindingStoreTests.cs
GFramework.Godot/Input/GodotInputBindingStore.cs
GFramework.Godot/Input/GodotInputMapBackend.cs
GFramework.Godot/Input/IGodotInputMapBackend.cs
ai-plan/public/input-system-godot-integration/traces/input-system-godot-integration-trace.md`),
capture the CLI output (pass/fail and any file list), and update the markdown
entry in input-system-godot-integration-tracking.md by replacing the "待本轮验证补录"
marker with the actual verification result and any relevant failing filenames or
error messages from the command; if you prefer automation, add a small
verification script that runs that command and writes the formatted result back
into the same markdown entry.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In
`@ai-plan/public/input-system-godot-integration/todos/input-system-godot-integration-tracking.md`:
- Around line 46-47: The TODO entry shows the license-header check result as
"待本轮验证补录"—fix by running the exact command shown (`python3
scripts/license-header.py --check --paths GFramework.Game.Abstractions/README.md
GFramework.Game.Tests/Input/InputBindingStoreTests.cs
GFramework.Game/Input/InputBindingStore.cs
GFramework.Game/Input/InputDeviceTracker.cs
GFramework.Game/Input/UiInputDispatcher.cs GFramework.Game/README.md
GFramework.Godot.Tests/Input/GodotInputBindingStoreTests.cs
GFramework.Godot/Input/GodotInputBindingStore.cs
GFramework.Godot/Input/GodotInputMapBackend.cs
GFramework.Godot/Input/IGodotInputMapBackend.cs
ai-plan/public/input-system-godot-integration/traces/input-system-godot-integration-trace.md`),
capture the CLI output (pass/fail and any file list), and update the markdown
entry in input-system-godot-integration-tracking.md by replacing the "待本轮验证补录"
marker with the actual verification result and any relevant failing filenames or
error messages from the command; if you prefer automation, add a small
verification script that runs that command and writes the formatted result back
into the same markdown entry.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 457c4f2e-cbb5-4f16-981d-70cf279026b6

📥 Commits

Reviewing files that changed from the base of the PR and between ebbef32 and 5f9589e.

📒 Files selected for processing (12)
  • GFramework.Game.Abstractions/README.md
  • GFramework.Game.Tests/Input/InputBindingStoreTests.cs
  • GFramework.Game/Input/InputBindingStore.cs
  • GFramework.Game/Input/InputDeviceTracker.cs
  • GFramework.Game/Input/UiInputDispatcher.cs
  • GFramework.Game/README.md
  • GFramework.Godot.Tests/Input/GodotInputBindingStoreTests.cs
  • GFramework.Godot/Input/GodotInputBindingStore.cs
  • GFramework.Godot/Input/GodotInputMapBackend.cs
  • GFramework.Godot/Input/IGodotInputMapBackend.cs
  • ai-plan/public/input-system-godot-integration/todos/input-system-godot-integration-tracking.md
  • ai-plan/public/input-system-godot-integration/traces/input-system-godot-integration-trace.md
✅ Files skipped from review due to trivial changes (2)
  • GFramework.Game/README.md
  • GFramework.Game.Abstractions/README.md
🚧 Files skipped from review as they are similar to previous changes (6)
  • GFramework.Game/Input/UiInputDispatcher.cs
  • GFramework.Game/Input/InputDeviceTracker.cs
  • GFramework.Godot/Input/IGodotInputMapBackend.cs
  • GFramework.Godot/Input/GodotInputBindingStore.cs
  • GFramework.Godot/Input/GodotInputMapBackend.cs
  • GFramework.Game/Input/InputBindingStore.cs
📜 Review details
⏰ Context from checks skipped due to timeout of 900000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Code Quality & Security
  • GitHub Check: Analyze (C#)
🧰 Additional context used
📓 Path-based instructions (6)
**/*.cs

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.cs: Apply [Log] attribute for automatic logging field and logging helper method generation
Apply [Priority] attribute for automatic priority comparison implementation generation
Apply [GenerateEnumExtensions] attribute to generate enumeration extension capabilities
Apply [ContextAware] attribute to automatically implement IContextAware boilerplate logic

**/*.cs: All public, protected, and internal types and members MUST include XML documentation comments (///)
XML documentation comments MUST use <summary>, <param>, <returns>, <exception>, and <remarks> where applicable, explaining intent, contract, and usage constraints instead of restating syntax
If a member participates in lifecycle, threading, registration, or disposal behavior, document that behavior explicitly in XML documentation
Add inline comments for non-trivial logic, concurrency or threading behavior, performance-sensitive paths, workarounds and compatibility constraints, edge cases, registration order, lifecycle sequencing, and generated code assumptions
Avoid obvious comments such as // increment i
Methods with non-trivial logic MUST document: The core idea, Key decisions, and Edge case handling, if any
Comments MUST NOT be trivial, redundant, or misleading. Prefer explaining why and when, not just what. Code should remain understandable without requiring external context. Prefer slightly more explanation over too little for framework code
Do not rely on implicit imports. Declare every required using explicitly
Write null-safe code that respects nullable annotations instead of suppressing warnings by default
Use the namespace pattern GFramework.{Module}.{Feature} with PascalCase segments
Follow standard C# naming: Types, methods, properties, events, and constants use PascalCase; Interfaces use I prefix; Parameters and locals use camelCase; Private fields use _camelCase
Use 4 spaces for indentation. Do not use tabs
Use Allman braces
Keep using directives at the top...

Files:

  • GFramework.Godot.Tests/Input/GodotInputBindingStoreTests.cs
  • GFramework.Game.Tests/Input/InputBindingStoreTests.cs
**/*.Tests/**/*.cs

📄 CodeRabbit inference engine (AGENTS.md)

**/*.Tests/**/*.cs: Mirror the source structure in test projects whenever practical
Reuse existing architecture test infrastructure when relevant: ArchitectureTestsBase<T>, SyncTestArchitecture, AsyncTestArchitecture

Files:

  • GFramework.Godot.Tests/Input/GodotInputBindingStoreTests.cs
  • GFramework.Game.Tests/Input/InputBindingStoreTests.cs
ai-plan/public/**

📄 CodeRabbit inference engine (AGENTS.md)

ai-plan/public/**: Contributors MUST keep committed ai-plan/public/** content safe to publish in Git history
Active tracking and trace files are recovery entrypoints, not append-only changelogs. They MUST stay concise enough for boot to locate the current recovery point quickly
When completed and validated stages begin to accumulate, contributors MUST archive their detailed history out of the active todos/ and traces/ entry files in the same change. Keep only the current recovery point, active facts, active risks, immediate next step, and pointers to the relevant archive files in the default boot path
When a topic is fully complete, move the entire topic directory under ai-plan/public/archive/<topic>/ and remove it from ai-plan/public/README.md in the same change
When a task spans multiple commits or is likely to exceed a single agent context window, update both the recovery document and the trace at each meaningful milestone before pausing or handing work off
If subagents are used on a complex task, the main agent MUST capture the delegated scope and any accepted findings in the active recovery document or trace before continuing implementation

Files:

  • ai-plan/public/input-system-godot-integration/todos/input-system-godot-integration-tracking.md
  • ai-plan/public/input-system-godot-integration/traces/input-system-godot-integration-trace.md
ai-plan/**

📄 CodeRabbit inference engine (AGENTS.md)

ai-plan/**: Never write secrets, tokens, credentials, private keys, machine usernames, home-directory paths, hostnames, IP addresses, proprietary URLs, or other sensitive environment details into any ai-plan/** file
Never record absolute file-system paths in ai-plan/**; use repository-relative paths, branch names, PR numbers, or stable document identifiers instead

Files:

  • ai-plan/public/input-system-godot-integration/todos/input-system-godot-integration-tracking.md
  • ai-plan/public/input-system-godot-integration/traces/input-system-godot-integration-trace.md
ai-plan/public/**/todos/**

📄 CodeRabbit inference engine (AGENTS.md)

ai-plan/public/**/todos/**: When working from a tracked implementation plan, contributors MUST update the corresponding tracking document under ai-plan/public/<topic>/todos/ in the same change
Tracking updates MUST reflect completed work, newly discovered issues, validation results, and the next recommended recovery point
For any multi-step refactor, migration, or cross-module task, contributors MUST create or adopt a dedicated recovery document under ai-plan/public/<topic>/todos/ before making substantive code changes
Recovery documents MUST record the current phase, the active recovery point identifier, known risks, and the next recommended resume step so another contributor or subagent can continue the work safely

Files:

  • ai-plan/public/input-system-godot-integration/todos/input-system-godot-integration-tracking.md
ai-plan/public/**/traces/**

📄 CodeRabbit inference engine (AGENTS.md)

Contributors MUST maintain a matching execution trace under ai-plan/public/<topic>/traces/ for complex work. The trace should record the current date, key decisions, validation milestones, and the immediate next step

Files:

  • ai-plan/public/input-system-godot-integration/traces/input-system-godot-integration-trace.md
🧠 Learnings (1)
📚 Learning: 2026-04-06T12:45:43.921Z
Learnt from: GeWuYou
Repo: GeWuYou/GFramework PR: 190
File: GFramework.Game/Config/GameConfigBootstrap.cs:1-3
Timestamp: 2026-04-06T12:45:43.921Z
Learning: In the GeWuYou/GFramework repository, C# files may omit explicit `using System*` imports because the project-wide `GlobalUsings.cs` (referenced via manual global `using` directives) supplies common namespaces (e.g., `System`, `System.Threading`, `System.Threading.Tasks`). During code review, do not flag missing `using System...` directives in `.cs` files as long as `GlobalUsings.cs` is present/used to provide those namespaces.

Applied to files:

  • GFramework.Godot.Tests/Input/GodotInputBindingStoreTests.cs
  • GFramework.Game.Tests/Input/InputBindingStoreTests.cs
🪛 LanguageTool
ai-plan/public/input-system-godot-integration/todos/input-system-godot-integration-tracking.md

[grammar] ~16-~16: Ensure spelling is correct
Context: ...ts的新增回归,并补docs/zh-CN/game/input.mddocs/zh-CN/godot/input.md - 已处理 PR#346` 的首轮 review follow-up,修复只读查询污染...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)

ai-plan/public/input-system-godot-integration/traces/input-system-godot-integration-trace.md

[uncategorized] ~73-~73: 您的意思是“"不"录”?
Context: ...# 下一步 1. 运行针对本次改动文件的 license-header 检查并补录结果 2. 如需继续消化 PR review,再单独评估值对象切换到 `rec...

(BU)

🔇 Additional comments (4)
ai-plan/public/input-system-godot-integration/traces/input-system-godot-integration-trace.md (1)

1-75: 追踪文档结构清晰,符合规范。

该追踪文档正确记录了 2026-05-11 针对 PR #346 的 review follow-up,包含:

  • 明确的恢复点标识(RP-001)
  • 核心问题清单与修复决策
  • 新增回归测试的验证结果
  • 清晰的下一步行动项

文档符合 ai-plan/public/**/traces/** 的要求,保持简洁并聚焦当前恢复点。

ai-plan/public/input-system-godot-integration/todos/input-system-godot-integration-tracking.md (1)

1-55: 跟踪文档结构完整,恢复点清晰。

该跟踪文档正确实现了 ai-plan/public/**/todos/** 的要求:

  • 明确的恢复点编号(INPUT-GODOT-RP-001)与当前阶段(Phase 1)
  • 完整的目标、状态、风险与验证说明
  • 清晰的下一步行动建议

文档聚焦当前恢复点,便于后续恢复或移交工作。

GFramework.Game.Tests/Input/InputBindingStoreTests.cs (1)

1-96: 测试覆盖全面,结构清晰。

该测试文件正确实现了对 InputBindingStore 的行为验证:

  • 绑定冲突时的交换语义
  • 重置操作恢复默认快照
  • 查询缺失动作时不污染快照(新增回归测试)

所有测试方法均包含清晰的 XML 文档说明,使用 Assert.Multiple 组织相关断言,符合 NUnit 最佳实践。

GFramework.Godot.Tests/Input/GodotInputBindingStoreTests.cs (1)

1-258: 测试覆盖完整,FakeInputMapBackend 实现清晰。

该测试文件正确验证了 GodotInputBindingStore 的核心行为:

  • 快照导出反映后端绑定
  • 快照导入更新后端绑定
  • 导入快照时清空缺失动作的后端绑定(新增回归测试,lines 88-140)
  • 主绑定设置时保留冲突交换语义

FakeInputMapBackend(lines 196-256)提供了确定性的测试桩实现,正确分离了默认绑定与当前绑定的状态管理,使测试场景可重复验证。

coderabbitai[bot]
coderabbitai Bot previously approved these changes May 11, 2026
- 修复 InputBindingStore 的线程安全使用说明并消除 GodotInputBindingCodec 的重复键码计算\n- 修复 GodotInputMapBackend 在全量重置时未移除运行时新增动作的语义偏差并补回归测试\n- 更新 input-system-godot-integration 的 tracking 与 trace,补录 PR review follow-up 验证结果
@github-actions

Copy link
Copy Markdown

Summary

Tests 📝 Passed ✅ Failed ❌ Skipped ⏭️ Other ❓ Flaky 🍂 Duration ⏱️
2353    ↑1 2353    ↑1 0 0 0 0 38.0s    ↓1.4s

Test Results

passed 2353 passed ↑1

Details

tests 2353 tests ↑1
clock 38.0s ↓1.4s
tool nunit
build CI - Build & Test arrow-right build-and-test link #1105
pull-request feat(input): 新增统一输入抽象与Godot集成 link #346

Insights

Average Tests per Run Total Flaky Tests Total Failed Slowest Test (p95)
2352 0 0 4.6s

build-and-test: Run #1105

Tests 📝 Passed ✅ Failed ❌ Skipped ⏭️ Pending ⏳ Other ❓ Flaky 🍂 Duration ⏱️
2353 2353 0 0 0 0 0 38.0s

🎉 All tests passed!

Slowest Tests

Test 📝 Results 📊 Duration (avg) ⏱️ Duration (p95) ⏱️
CreateStream_Should_ResolveCqrsRuntime_OnlyOnce_When_AccessedConcurrently 3 3.8s 4.6s
Does_Not_Report_When_FieldInjectedModel_Is_Registered 3 2.3s 2.5s
Generates_Scene_Behavior_Boilerplate 3 1.9s 2.0s
CleanupDuringAcquire_Should_NotCauseRaceCondition 3 1.1s 1.1s
Append_ShouldNotBlock 3 1.0s 1.0s
Context_Caching_Should_Improve_Performance 3 780ms 782ms
PendingCount_ShouldReflectQueuedEntries 3 501ms 501ms
Cleanup_Should_NotRemoveActiveLocks 3 404ms 405ms
Cleanup_Should_RemoveUnusedLocks 3 401ms 401ms
Generates_Module_Install_Method_In_Attribute_Order 3 299ms 320ms

± Comparison with run #1103 at a7cae5d | 🎉 No failed tests detected across all runs. | 🍂 No flaky tests detected across all runs. | ⏱️ Measured over 3 runs.

Github Test Reporter by CTRF 💚

@GeWuYou GeWuYou merged commit cacf238 into main May 11, 2026
7 checks passed
@GeWuYou GeWuYou deleted the feat/input-system-godot-integration branch May 11, 2026 03:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant